package com.mac.intellect_flow.admin.controller.monitor;

import cn.hutool.core.collection.CollectionUtil;
import com.mac.intellect_flow.constant.CommonConstant;
import com.mac.intellect_flow.except.ServiceException;
import com.mac.intellect_flow.framework.model.LoginUser;
import com.mac.intellect_flow.framework.util.JwtUtil;
import com.mac.intellect_flow.redis.util.RedisUtil;
import com.mac.intellect_flow.reply.PageParam;
import com.mac.intellect_flow.reply.PageResult;
import com.mac.intellect_flow.reply.R;
import com.mac.intellect_flow.sys.model.SysUserOnline;
import com.mac.intellect_flow.sys.service.SysUserOnlineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 在线用户监控
 * 
 * @author mac
 */
@Tag(name = "在线用户监控")
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController {
    @Autowired
    private SysUserOnlineService userOnlineService;

    @Autowired
    private RedisUtil redisCache;

    @PreAuthorize("@ps.hasPermi('monitor:online:list')")
    @GetMapping("/list")
    public R<PageResult<SysUserOnline>> list(String ipaddr, String userName, PageParam pageParam) {
        Collection<String> keys = redisCache.keys(CommonConstant.ADMIN_LOGIN_TOKEN_KEY + "*");
        List<String> sortKeys = new ArrayList<>(keys);
        Collections.sort(sortKeys);
        int end = pageParam.getPageNo() * pageParam.getPageSize();
        int start = (pageParam.getPageNo() - 1) * pageParam.getPageSize();
        if (start > sortKeys.size()){
           throw new ServiceException("已经是最后一页了");
        }
        if (end > sortKeys.size()) {
            end = sortKeys.size();
        }
        sortKeys = sortKeys.subList(start, end);
        List<SysUserOnline> userOnlineList = new ArrayList<>();
        for (String key : sortKeys) {
            LoginUser user = redisCache.getCacheObject(key);
            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
                userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
            }
            else if (StringUtils.isNotEmpty(ipaddr)) {
                userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
            }
            else if (StringUtils.isNotEmpty(userName) && Objects.nonNull(user)) {
                userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
            }
            else {
                userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
            }
        }
        return R.success(new PageResult<>(userOnlineList, (long)keys.size(), pageParam.getPageSize(), pageParam.getPageNo()));
    }

    /**
     * 强退用户
     */
    @Operation(summary = "强退用户")
    @PreAuthorize("@ps.hasPermi('monitor:online:forceLogout')")
    @DeleteMapping("/{tokenId}")
    public R forceLogout(@PathVariable String tokenId) {
        JwtUtil.delRedisLoginUser(null,tokenId,true);
        return R.success();
    }


    @Operation(summary = "账户解锁")
    @PreAuthorize("@ps.hasPermi('monitor:logininfor:unlock')")
    @GetMapping("/unlock/{userName}")
    public R unlock(@PathVariable("userName") String userName) {
        if (redisCache.hasKey(getCacheKey(userName))) {
            redisCache.deleteObject(getCacheKey(userName));
        }
        return R.success();
    }

    private String getCacheKey(String username) {
        return CommonConstant.PWD_ERR_CNT_KEY + username;
    }
}
